#include "analyzer.h"

Analyzer::Analyzer(QObject *parent)
    :QObject(parent)
{
    isTest=false;
}

void Analyzer::onConnect()
{
    odbc=odbc_getConnectionFromSHM(SHM_KEY,ENTRY_U8,SQL_U8_CONNECTION);
    connected(odbc.open());
}

int Analyzer::getStock(const QString &invCode)
{
    int result = 0;
    QSqlQuery query(odbc);
    auto sql=QString("select sum(iQuantity) as total from CurrentStock where cInvCode='%1' AND cWhCode in ('001','003')")
            .arg(invCode);
    query.exec(sql);
    if(query.next())
    {
        result = query.value(0).toInt();
        stockCache.insert(invCode,result);
    }

    return result;
}

void Analyzer::onReset_DL(const QString &beginDate)
{
    if(!odbc.isOpen())
    {
        appendMessage("数据库连接异常，操作终止");
        return;
    }

    if(!stockCache.isEmpty())
        stockCache.clear();

    QSqlQuery query(odbc);
    bool result=query.exec(QString("update DispatchList set cDefine15=null where dDate >= '%1'")
                           .arg(beginDate));
    if(result)
        appendMessage(QString("[%1] 操作完成，发货标记已清除")
                      .arg(CurrentDateTime));
    else
        appendMessage(QString("[%1] 操作失败，错误信息：%2")
                      .arg(CurrentDateTime).arg(query.lastError().text()));

}

void Analyzer::onAnalyze_DL(const QString &beginDate)
{
    if(!odbc.isOpen())
    {
        appendMessage("数据库连接异常，操作终止");
        return;
    }

    appendMessage(QString("[%1] 发货单筛选操作开始--").arg(CurrentDateTime));
    analyzing(true);

    // 审核中，非退货
    QSqlQuery query(odbc);
    query.exec(QString("select DLID,cDLCode from DispatchList where dDate >= '%1' and iverifystate=1 and bReturnFlag=0")
               .arg(beginDate));
    int row=0,flag=0;
    while (query.next()) {
        auto dlid=query.value(0).toString();
        auto cDLCode=query.value(1).toString();
        if(itemAnalyze_DL(dlid))
        {
            if(tagUp_DL(dlid))
            {
                appendMessage(QString("%1 符合发货条件，已标记").arg(cDLCode));
                flag +=1;
            }
        }
        row += 1;
    }
    appendMessage(QString("[%1] 发货单筛选操作完成，本次共处理 %2 条，标记 %3 条")
                  .arg(CurrentDateTime).arg(row).arg(flag));
    analyzing(false);
}

bool Analyzer::itemAnalyze_DL(const QString &dlid)
{
    int flag=0;
    QSqlQuery query(odbc);
    auto sql=QString("select cInvCode,sum(iQuantity) as delivery from DispatchLists where DLID='%1' group by cInvCode")
            .arg(dlid);
    if(isTest)
        appendMessage(sql);
    query.exec(sql);
    while (query.next()) {
        auto invCode=query.value(0).toString();
        auto delivery=query.value(1).toInt();  // 出库数量
        if(invCode == "txfwf-1")
        {
            appendMessage("检测到txfwf-1，跳过");
            continue;
        }

        if(!cellAnalyze_DL(invCode,delivery))
            flag+=1;
    }
    return flag==0;
}

bool Analyzer::cellAnalyze_DL(const QString &invCode, int delivery)
{
    int stock=0;
    if(stockCache.contains(invCode))
        stock=stockCache.value(invCode);
    else
        stock=getStock(invCode);

    if(stock <= 0 || stock < delivery)
    {
        if(isTest)
            appendMessage(QString("%1 现存量小于等于0 或者 现存量小于发货数量，跳过").arg(invCode));
        return false;
    }

    QSqlQuery query(odbc);
    auto sql=QString("select cInvDefine11,cInvDefine12 from Inventory where cInvCode='%1'")
            .arg(invCode);
    if(isTest)
        appendMessage(sql);

    query.exec(sql);
    if(query.next())
    {
        auto reserve=query.value(0).toInt();    //电商留存数
        auto restriction=query.value(1).toInt();    //发货限制数

        if(isTest)
            appendMessage(QString("正在检测 %1, 现存量 %2, 电商留存数 %3, 发货限制数 %4")
                          .arg(invCode).arg(stock).arg(reserve).arg(restriction));

        if(restriction > 0)
        {
            if( (stock - reserve - delivery) >= 0 && delivery <= restriction)
            {
                stock = stock - delivery;
                stockCache.insert(invCode,stock);
                return true;
            }
            else
                return false;
        }
        else
        {
            if( (stock - reserve - delivery) >= 0 )
            {
                stock = stock - delivery;
                stockCache.insert(invCode,stock);
                return true;
            }
            else
                return false;
        }
    }
    return false;
}

bool Analyzer::tagUp_DL(const QString &dlid)
{
    QSqlQuery query(odbc);
    bool result=query.exec(QString("update DispatchList set cDefine15=1 where DLID='%1'")
                           .arg(dlid));
    if(result)
        return true;
    else
    {
        qDebug() << query.lastError().text();
        return false;
    }
}

void Analyzer::onTest_DL(const QString &cDLCode)
{
    if(!odbc.isOpen())
        return;

    isTest=true;
    appendMessage(QString("现在开始测试，发货单号 %1").arg(cDLCode));
    QSqlQuery query(odbc);
    auto sql=QString("select DLID from DispatchList where cDLCode='%1'")
            .arg(cDLCode);
    if(isTest)
        appendMessage(sql);
    query.exec(sql);
    if(query.next())
    {
        auto dlid=query.value(0).toString();
        appendMessage(QString("已查询到DLID %1").arg(dlid));
        if(itemAnalyze_DL(dlid))
        {
            appendMessage("测试完成，符合发货条件");
        }
        else
            appendMessage("测试完成，不符合发货条件");
    }
    else
        appendMessage("未查询到DLID，测试终止");
    isTest=false;
}

void Analyzer::onReset_EB(const QString &beginDate)
{
    if(!odbc.isOpen())
    {
        appendMessage("数据库连接异常，操作终止");
        return;
    }

    if(!stockCache.isEmpty())
        stockCache.clear();

    QSqlQuery query(odbc);
    bool result=query.exec(QString("update EB_Trade set cDefine15=null,cExcoPrintStatus=0 where created >= '%1'")
                           .arg(beginDate));
    if(result)
        appendMessage(QString("[%1] 操作完成，发货标记已清除")
                      .arg(CurrentDateTime));
    else
        appendMessage(QString("[%1] 操作失败，错误信息：%2")
                      .arg(CurrentDateTime).arg(query.lastError().text()));
}

void Analyzer::onAnalyze_EB(const QString &beginDate)
{
    if(!odbc.isOpen())
    {
        appendMessage("数据库连接异常，操作终止");
        return;
    }

    appendMessage(QString("[%1] 电商订单筛选操作开始--").arg(CurrentDateTime));
    analyzing(true);

    // 审核中，非退货
    QSqlQuery query(odbc);
    query.exec(QString("select autoID from EB_Trade where sysStatus='Effective' AND created >= '%1' AND isHold=0 ")
               .arg(beginDate));
    int row=0,flag=0;
    while (query.next()) {
        auto autoID=query.value(0).toString();
        if(itemAnalyze_EB(autoID))
        {
            if(tagUp_EB(autoID))
            {
                appendMessage(QString("%1 符合发货条件，已标记").arg(autoID));
                flag +=1;
            }
        }
        row += 1;
    }
    appendMessage(QString("[%1] 电商订单筛选操作完成，本次共处理 %2 条，标记 %3 条")
                  .arg(CurrentDateTime).arg(row).arg(flag));
    analyzing(false);
}

bool Analyzer::itemAnalyze_EB(const QString &autoID)
{
    int flag=0;
    QSqlQuery query(odbc);
    auto sql=QString("select cInvCode,num from EB_Order as eo JOIN EB_Item as ei ON eo.cItemID=ei.OID where parentID='%1'")
            .arg(autoID);
    if(isTest)
        appendMessage(sql);
    query.exec(sql);
    while (query.next()) {
        auto invCode=query.value(0).toString();
        auto delivery=query.value(1).toInt();  // 出库数量
        if(invCode == "txfwf-1")
        {
            appendMessage("检测到txfwf-1，跳过");
            continue;
        }

        if(!cellAnalyze_EB(invCode,delivery))
            flag+=1;
    }
    return flag==0;
}

bool Analyzer::cellAnalyze_EB(const QString &invCode, int delivery)
{
    int stock=0;
    if(stockCache.contains(invCode))
        stock=stockCache.value(invCode);
    else
        stock=getStock(invCode);

    if(stock <= 0 || stock < delivery)
    {
        if(isTest)
            appendMessage(QString("%1 现存量小于等于0 或者 现存量小于发货数量，跳过").arg(invCode));
        return false;
    }

    QSqlQuery query(odbc);
    auto sql=QString("select cInvDefine12 from Inventory where cInvCode='%1'")
            .arg(invCode);
    if(isTest)
        appendMessage(sql);
    query.exec(sql);
    if(query.next())
    {
        auto restriction=query.value(0).toInt();    //发货限制数
        auto stock=getStock(invCode);      // 现存量

        if(!stockCache.contains(invCode))
            stockCache.insert(invCode,stock);

        if(isTest)
            appendMessage(QString("正在检测 %1, 现存量 %2, 发货限制数 %3")
                          .arg(invCode).arg(stock).arg(restriction));

        if(stock <= 0)
            return false;

        if(restriction > 0)
        {
            if( stock >= delivery && delivery <= restriction)
            {
                stock = stock - delivery;
                stockCache.insert(invCode,stock);
                return true;
            }
            else
                return false;
        }
        else
        {
            if( stock >= delivery )
            {
                stock = stock - delivery;
                stockCache.insert(invCode,stock);
                return true;
            }
            else
                return false;
        }
    }
    return false;
}

bool Analyzer::tagUp_EB(const QString &autoID)
{
    QSqlQuery query(odbc);
    bool result=query.exec(QString("update EB_Trade set cExcoPrintStatus=1,cDefine15=1 where autoID='%1'")
                           .arg(autoID));
    if(result)
        return true;
    else
    {
        qDebug() << query.lastError().text();
        return false;
    }
}

void Analyzer::onTest_EB(const QString &cTradeCode)
{
    if(!odbc.isOpen())
    {
        appendMessage("数据库连接异常，操作终止");
        return;
    }

    isTest=true;
    appendMessage(QString("现在开始测试，电商订单号 %1").arg(cTradeCode));

    QSqlQuery query(odbc);
    auto sql=QString("select autoID,cTradeCode from EB_Trade where cTradeCode='%1'")
            .arg(cTradeCode);
    if(isTest)
        appendMessage(sql);
    query.exec(sql);
    if(query.next())
    {
        auto autoID=query.value(0).toString();
        if(itemAnalyze_EB(autoID))
        {
            appendMessage("测试完成，符合发货条件");
        }
        else
            appendMessage("测试完成，不符合发货条件");
    }
    else
        appendMessage("未查询到电商订单号，测试终止");
    isTest=false;
}
